﻿using System.Diagnostics.Contracts;
using System.Security.AccessControl;
using Company.IO.Interfaces;

// ReSharper disable CheckNamespace
public static class FileSystemExtension
// ReSharper restore CheckNamespace
{
    public static IStream CreateFile(this IFileSystem fileSystem, string path)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Create(path);
    }

    public static IStream CreateFile(this IFileSystem fileSystem, string path, int bufferSize)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Create(path, bufferSize);
    }

    public static IStream CreateFile(this IFileSystem fileSystem, string path, int bufferSize, FileOptions fileOptions)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Create(path, bufferSize, fileOptions);
    }

    public static IStream CreateFile(this IFileSystem fileSystem, string path, int bufferSize, FileOptions fileOptions,
        FileSecurity fileSecurity)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Create(path, bufferSize, fileOptions, fileSecurity);
    }

    public static IStream OpenFile(this IFileSystem fileSystem, string path, FileMode fileMode)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Open(path, fileMode);
    }

    public static IStream OpenFile(this IFileSystem fileSystem, string path, FileMode fileMode, FileAccess fileAccess)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Open(path, fileMode, fileAccess);
    }

    public static IStream OpenFile(this IFileSystem fileSystem, string path, FileMode fileMode, FileAccess fileAccess,
        FileShare fileShare)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.File.Open(path, fileMode, fileAccess, fileShare);
    }

    public static void DeleteFile(this IFileSystem fileSystem, string path)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.File != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        fileSystem.File.Delete(path);
    }

    public static string GetCurrentDirectory(this IFileSystem fileSystem)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Directory != null);

        return fileSystem.Directory.GetCurrentDirectory();
    }

    public static string Combine(this IFileSystem fileSystem, params string[] paths)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Path != null);

        Contract.Requires(paths != null);
        Contract.Requires(paths.Length > 0);

        return fileSystem.Path.Combine(paths);
    }

    public static string Combine(this IFileSystem fileSystem, string path1, string path2)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Path != null);

        Contract.Requires(!string.IsNullOrEmpty(path1));
        Contract.Requires(!string.IsNullOrEmpty(path2));

        return fileSystem.Path.Combine(path1, path2);
    }

    public static string Combine(this IFileSystem fileSystem, string path1, string path2, string path3)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Path != null);

        Contract.Requires(!string.IsNullOrEmpty(path1));
        Contract.Requires(!string.IsNullOrEmpty(path2));
        Contract.Requires(!string.IsNullOrEmpty(path3));

        return fileSystem.Path.Combine(path1, path2, path3);
    }

    public static string Combine(this IFileSystem fileSystem, string path1, string path2, string path3, string path4)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Path != null);

        Contract.Requires(!string.IsNullOrEmpty(path1));
        Contract.Requires(!string.IsNullOrEmpty(path2));
        Contract.Requires(!string.IsNullOrEmpty(path3));
        Contract.Requires(!string.IsNullOrEmpty(path4));

        return fileSystem.Path.Combine(path1, path2, path3, path4);
    }

    public static string GetFullPath(this IFileSystem fileSystem, string path)
    {
        Contract.Requires(fileSystem != null);
        Contract.Requires(fileSystem.Path != null);

        Contract.Requires(!string.IsNullOrEmpty(path));

        return fileSystem.Path.GetFullPath(path);
    }
}